/** 渲染图元参数
 * @ 标  识: hchhIOT
 * @ 作  者: 阿拉丁矿工 黄传鸿 <hchhyzc@foxmail.com>
 */

/* ================================================================================================ */
// 🍀引入
/* ================================================================================================ */
import * as d3 from "d3";//
import { fabric } from "fabric";
/**图元端函数引入*/
import {
  onGetLineMiddle,
  onGetCircleBisectionPoint,
  onAnimationHandle,
  onPatternGenerator,//填充图案生成器
} from "@/functions";
import {
  CoordinateType,
  PelInfoType,
  AnimateType,
  PlaceEnum,
  PlaceType,
  EventType
} from "@/defines";//定义引入
import { useEditorStore } from "../../store"; // 引入存储
const myStore = useEditorStore(); // 使用存储

/**———————————————————————————————————————————————————————————————————————————————————————————————— */
//                                ★ 类型
/**———————————————————————————————————————————————————————————————————————————————————————————————— */


/* ================================================================================================ */
//                                函数
/* ================================================================================================ */

/**————————————————————————————————————————————————————————————————————————————————————————————————*/
//                                ★ SVG图元
/**————————————————————————————————————————————————————————————————————————————————————————————————*/

/** 渲染标签-线 rander*/
const onRenderLine = (pelInfo: any): any => {
  console.log("✍ 渲染标签-线");
  // let Canvas = document.querySelector("#h_canvas") as HTMLCanvasElement
  // const ctx = Canvas.getContext('2d') as CanvasRenderingContext2D;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 转储、建立参数
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  //------------------------------|属性
  let {
    x1Val,                //坐标X1值
    y1Val,                //坐标Y1值
    x2Val,                //坐标X2值
    y2Val,                //坐标Y2值
    strokeVal,            //轮廓颜色值
    strokeWidthVal,       //轮廓宽度
    strokeLinecapVal,     //线端样式
    strokeDasharrayVal,   //虚线值
    strokeDashoffsetVal,  //虚线偏移值
    opacityVal            //透明度值
  } = pelInfo.attrs;



  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pidVal !== "none") {

  }
  if (pidVal === "none") {

  }

};

/** 渲染标签-圆 */
const onRenderCircle = (pelInfo: any): any => {
  // console.log("✍ 渲染标签-圆")
  // console.log(pelInfo)

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 水平坐标值 */
  let leftVal = Number(pelInfo.attrs.cx.val);
  /** 垂直坐标值 */
  let topVal = Number(pelInfo.attrs.cy.val);
  /** 圆半径 */
  let RadiusVal = Number(pelInfo.attrs.radius.val);

  //------------------------------------------------ 填充
  /** 填充颜色*/
  let fillVal = String(pelInfo.attrs.fill.val);
  /** 填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;*/
  let fillOptVal = (pelInfo.attrs.fill.fillOpt);
  /** 填充图案*/
  let fillPatternVal = Number(pelInfo.attrs.fill.fillPattern);
  /** 填充尺寸*/
  let fillSizeVal = Number(pelInfo.attrs.fill.fillSize);
  /** 填充比例*/
  let fillRatioVal = Number(pelInfo.attrs.fill.fillRatio);
  /** 填充Id*/
  let fillIdVal = String(pelInfo.attrs.fill.fillId);
  /** 填充坐标x1*/
  let fillX1Val = Number(pelInfo.attrs.fill.fillX1);
  /** 填充坐标x2*/
  let fillX2Val = Number(pelInfo.attrs.fill.fillX2);
  /** 填充坐标y1*/
  let fillY1Val = Number(pelInfo.attrs.fill.fillY1);
  /** 填充坐标y2*/
  let fillY2Val = Number(pelInfo.attrs.fill.fillY2);
  /** 填充坐标cx*/
  let fillCXVal = Number(pelInfo.attrs.fill.fillCX);
  /** 填充坐标cy*/
  let fillCYVal = Number(pelInfo.attrs.fill.fillCY);
  /** 填充半径r*/
  let fillRVal = Number(pelInfo.attrs.fill.fillR);
  /** 填充偏移量*/
  let fillOffsetsVal = pelInfo.attrs.fill.offsets;

  /** 轮廓颜色*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);
  /** 轮廓透明度 */
  let strokeOpacityVal = Number(pelInfo.attrs.strokeOpacity.val);
  /** 填充透明度 */
  let fillOpacityVal = Number(pelInfo.attrs.fillOpacity.val);


  //填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;
  if (fillOptVal === 1/*颜色填充*/) {
    if (pidVal !== "none") {

    }
    if (pidVal === "none") {

    }
  }
  if (fillOptVal === 2/*图案填充*/) {
    if (pidVal !== "none") {

    }
    if (pidVal === "none") {

    }
  }
  if (fillOptVal === 3/*线性渐变填充*/) {
    if (pidVal !== "none") {

    }
    if (pidVal === "none") {

    }
  }
  if (fillOptVal === 4/*放射渐变填充*/) {

    if (pidVal !== "none") {

    }
    if (pidVal === "none") {

    }
  }


};

/** 渲染标签-椭圆 */
const onRenderEllipse = (pelInfo: any): any => {
  // console.log("✍ 渲染标签-椭圆");
  // console.log(pelInfo);
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 水平坐标值 */
  let leftVal = Number(pelInfo.attrs.cx.val);
  /** 垂直坐标值 */
  let topVal = Number(pelInfo.attrs.cy.val);
  /** 圆半径X */
  let RXVal = Number(pelInfo.attrs.radiusX.val);
  /** 圆半径Y */
  let RYVal = Number(pelInfo.attrs.radiusY.val);
  //------------------------------------------------
  /** 填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;*/
  let fillOptVal = Number(pelInfo.attrs.fill.fillOpt);
  /** 填充颜色*/
  let fillVal = String(pelInfo.attrs.fill.val);
  /** 填充图案*/
  let fillPatternVal = String(pelInfo.attrs.fill.fillPattern);
  /** 填充比例*/
  let fillRatioVal = Number(pelInfo.attrs.fill.fillRatio);
  /** 填充Id*/
  let fillIdVal = String(pelInfo.attrs.fill.fillId);
  /** 填充坐标x1*/
  let fillX1Val = Number(pelInfo.attrs.fill.fillX1);
  /** 填充坐标x2*/
  let fillX2Val = Number(pelInfo.attrs.fill.fillX2);
  /** 填充坐标y1*/
  let fillY1Val = Number(pelInfo.attrs.fill.fillY1);
  /** 填充坐标y2*/
  let fillY2Val = Number(pelInfo.attrs.fill.fillY2);
  /** 填充坐标cx*/
  let fillCXVal = Number(pelInfo.attrs.fill.fillCX);
  /** 填充坐标cy*/
  let fillCYVal = Number(pelInfo.attrs.fill.fillCY);
  /** 填充半径r*/
  let fillRVal = Number(pelInfo.attrs.fill.fillR);
  /** 填充偏移量*/
  let fillOffsetsVal = pelInfo.attrs.fill.offsets;

  /** 轮廓颜色*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);
  /** 轮廓透明度 */
  let strokeOpacityVal = Number(pelInfo.attrs.strokeOpacity.val);
  /** 填充透明度 */
  let fillOpacityVal = Number(pelInfo.attrs.fillOpacity.val);



};

/** 渲染标签-三点弧线 */
const onRenderArc = (pelInfo: any): any => {
  // console.log("✍ 渲染标签-三点弧线");
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 转储、建立参数
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);
  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 开始点X值 */
  let startXVal = Number(pelInfo.attrs.startX.val);
  /** 开始点Y值 */
  let startYVal = Number(pelInfo.attrs.startY.val);
  /** 控制点X值 */
  let ctrlXVal = Number(pelInfo.attrs.ctrlX.val);
  /** 控制点Y值 */
  let ctrlYVal = Number(pelInfo.attrs.ctrlY.val);
  /** 终点X值 */
  let endXVal = Number(pelInfo.attrs.endX.val);
  /** 终点Y值 */
  let endYVal = Number(pelInfo.attrs.endY.val);
  /** 轮廓颜色值*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线值 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移值 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 透明度值 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);

};

/** 渲染标签-圆分多边形 */
const onRenderCirclePolygon = (pelInfo: any) => {
  // console.log("✍ 渲染标签-圆分多边形");
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);
  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 圆心坐标CX */
  let leftVal = Number(pelInfo.attrs.cx.val);
  /** 圆心坐标CY */
  let topVal = Number(pelInfo.attrs.cy.val);
  /** 圆半径 */
  let radius = Number(pelInfo.attrs.circleRadius.val);
  //------------------------------------------------
  /** 填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;*/
  let fillOptVal = Number(pelInfo.attrs.fill.fillOpt);
  /** 填充颜色*/
  let fillVal = String(pelInfo.attrs.fill.val);
  /** 填充图案*/
  let fillPatternVal = String(pelInfo.attrs.fill.fillPattern);
  /** 填充比例*/
  let fillRatioVal = Number(pelInfo.attrs.fill.fillRatio);
  /** 填充Id*/
  let fillIdVal = String(pelInfo.attrs.fill.fillId);
  /** 填充坐标x1*/
  let fillX1Val = Number(pelInfo.attrs.fill.fillX1);
  /** 填充坐标x2*/
  let fillX2Val = Number(pelInfo.attrs.fill.fillX2);
  /** 填充坐标y1*/
  let fillY1Val = Number(pelInfo.attrs.fill.fillY1);
  /** 填充坐标y2*/
  let fillY2Val = Number(pelInfo.attrs.fill.fillY2);
  /** 填充坐标cx*/
  let fillCXVal = Number(pelInfo.attrs.fill.fillCX);
  /** 填充坐标cy*/
  let fillCYVal = Number(pelInfo.attrs.fill.fillCY);
  /** 填充半径r*/
  let fillRVal = Number(pelInfo.attrs.fill.fillR);
  /** 填充偏移量*/
  let fillOffsetsVal = pelInfo.attrs.fill.offsets;

  /** 轮廓颜色*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);
  /** 轮廓透明度 */
  let strokeOpacityVal = Number(pelInfo.attrs.strokeOpacity.val);
  /** 填充透明度 */
  let fillOpacityVal = Number(pelInfo.attrs.fillOpacity.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 求圆周上等分点的坐标
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /**等分数量 */
  let quantity = Number(pelInfo.attrs.quantity.val);
  /** 路径点*/
  let pathPoints = onGetCircleBisectionPoint(leftVal, topVal, radius, quantity);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画标签声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-开始点X */
  let startXAnHtml = ``;

  //------------------------------|变换-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平移动 */
  let translateXAnHtml = ``;
  /** 动画标签-垂直移动 */
  let translateYAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /** 动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-填充颜色*/
  let fillAnHtml = ``;
  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;
  /** 动画标签-轮廓透明度 */
  let strokeOpacityAnHtml = ``;
  /** 动画标签-填充透明度 */
  let fillOpacityAnHtml = ``;

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
    // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "roate", "XML");
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
    // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "scale", "XML");
    scaleAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平移动 translateXVal translateXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateX.enable) {
    // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateX, "", "XML");
    if (
      pelInfo.animations.translateX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateXVal = Number(AnVal);
    }
    translateXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直移动 translateYVal translateYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateY.enable) {
    // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateY, "", "XML");
    if (
      pelInfo.animations.translateY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateYVal = Number(AnVal);
    }
    translateYAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
    // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "skewX", "XML");
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
    // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "skewY", "XML");
    skewYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
    // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
    // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
    // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
    // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDashoffset.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充颜色 fillVal;fillAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fill.enable) {
    // console.log("填充颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.fill, "fill", "CSS");
    if (
      pelInfo.animations.fill.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillVal = String(AnVal);
    }
    fillAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
    // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
 /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
    // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
    // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓透明度 strokeOpacityVal;strokeOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeOpacity.enable) {
    // console.log("轮廓透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeOpacity,
      "stroke-opacity",
      "XML"
    );
    if (
      pelInfo.animations.strokeOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeOpacityVal = Number(AnVal);
    }
    strokeOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充透明度 fillOpacityVal;fillOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fillOpacity.enable) {
    // console.log("填充透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.fillOpacity,
      "fill-opacity",
      "XML"
    );
    if (
      pelInfo.animations.fillOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillOpacityVal = Number(AnVal);
    }
    fillOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    /*开始点Y*/ startXAnHtml +
    //-----------------------------------|公共动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    translateXAnHtml + //♈水平移动
    translateYAnHtml + //♈垂直移动
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动
    strokeAnHtml + //♈轮廓颜色
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    fillAnHtml + //♈填充
    opacityAnHtml + //♈元素透明度
    strokeOpacityAnHtml + //♈轮廓透明度
    fillOpacityAnHtml; //♈填充透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: leftVal - radius,
      y: topVal - radius,
    },
    /** 左 */
    l: {
      x: leftVal - radius,
      y: topVal,
    },
    /** 下左 */
    bl: {
      x: leftVal - radius,
      y: topVal + radius,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: leftVal,
      y: topVal - radius,
    },
    /** 中间 */
    m: {
      x: leftVal,
      y: topVal,
    },
    /** 下中 */
    bm: {
      x: leftVal,
      y: topVal + radius,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: leftVal + radius,
      y: topVal - radius,
    },
    /** 右 */
    r: {
      x: leftVal + radius,
      y: topVal,
    },
    /** 下右 */
    br: {
      x: leftVal + radius,
      y: topVal + radius,
    },
  };

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 标签路径点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let PathAdd = "";
  for (let index = 1; index < pathPoints.length; index++) {
    let X = pathPoints[index].x;
    let Y = pathPoints[index].y;
    PathAdd = PathAdd + `L${X},${Y} `;
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  //填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;
  if (fillOptVal === 1/*颜色填充*/) {
    if (pidVal !== "none"/*父id不为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></g>`;
    }
  }
  if (fillOptVal === 2/*图案填充*/) {
    if (pidVal !== "none"/*父id不为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></g>`;
    }
  }
  if (fillOptVal === 3/*线性渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><linearGradient id=${fillIdVal} x1=${fillX1Val}% y1=${fillY1Val}% x2=${fillX2Val}% y2=${fillY2Val}% >${offset}</linearGradient></defs>`

    if (pidVal !== "none"/*父id不为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></g>`;
    }
  }
  if (fillOptVal === 4/*放射渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><radialGradient id=${fillIdVal} cx=${fillCXVal}% cy=${fillCYVal}% r=${fillRVal}% >${offset}</radialGradient></defs>`

    if (pidVal !== "none"/*父id不为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></svg></g></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></g>`;
    }
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，渲染-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(myStore.pelSet));
  copyPels.forEach((element: any) => {
    // console.log(element.key);
    if (element.key === pelInfo.key) {
      // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  myStore.pelSet = copyPels;

};

/** 渲染标签-矩形 */
const onRenderRectangle = (pelInfo: any): any => {
  // console.log("✍ 渲染标签-矩形");
  // console.log(pelInfo);
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** x坐标值 */
  let leftVal = Number(pelInfo.attrs.left.val);
  /** y坐标值 */
  let topVal = Number(pelInfo.attrs.top.val);
  /** 宽度值 */
  let widthVal = Number(pelInfo.attrs.width.val);
  /** 高度值 */
  let heightVal = Number(pelInfo.attrs.height.val);
  /** 圆角x值 */
  let FXVal = Number(pelInfo.attrs.fx.val);
  /** 圆角x值 */
  let FYVal = Number(pelInfo.attrs.fy.val);

  //------------------------------------------------ 填充
  /** 填充颜色*/
  let fillVal = String(pelInfo.attrs.fill.val);
  /** 填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;*/
  let fillOptVal = (pelInfo.attrs.fill.fillOpt);
  /** 填充图案*/
  let fillPatternVal = Number(pelInfo.attrs.fill.fillPattern);
  /** 填充尺寸*/
  let fillSizeVal = Number(pelInfo.attrs.fill.fillSize);
  /** 填充比例*/
  let fillRatioVal = Number(pelInfo.attrs.fill.fillRatio);
  /** 填充Id*/
  let fillIdVal = String(pelInfo.attrs.fill.fillId);
  /** 填充坐标x1*/
  let fillX1Val = Number(pelInfo.attrs.fill.fillX1);
  /** 填充坐标x2*/
  let fillX2Val = Number(pelInfo.attrs.fill.fillX2);
  /** 填充坐标y1*/
  let fillY1Val = Number(pelInfo.attrs.fill.fillY1);
  /** 填充坐标y2*/
  let fillY2Val = Number(pelInfo.attrs.fill.fillY2);
  /** 填充坐标cx*/
  let fillCXVal = Number(pelInfo.attrs.fill.fillCX);
  /** 填充坐标cy*/
  let fillCYVal = Number(pelInfo.attrs.fill.fillCY);
  /** 填充半径r*/
  let fillRVal = Number(pelInfo.attrs.fill.fillR);
  /** 填充偏移量*/
  let fillOffsetsVal = pelInfo.attrs.fill.offsets;

  /** 轮廓颜色*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);
  /** 轮廓透明度 */
  let strokeOpacityVal = Number(pelInfo.attrs.strokeOpacity.val);
  /** 填充透明度 */
  let fillOpacityVal = Number(pelInfo.attrs.fillOpacity.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画标签声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|公共-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-矩形宽度动画 */
  let rectWidthAnHtml = ``;
  /** 动画标签-矩形高度动画 */
  let rectHeightAnHtml = ``;
  /** 动画标签-水平动画 */
  let leftAnHtml = ``;
  /** 动画标签-垂直动画 */
  let topAnHtml = ``;
  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /** 动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-填充颜色*/
  let fillAnHtml = ``;
  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;
  /** 动画标签-轮廓透明度 */
  let strokeOpacityAnHtml = ``;
  /** 动画标签-填充透明度 */
  let fillOpacityAnHtml = ``;



  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateVal rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
    // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "rotate", "XML");
    if (
      pelInfo.animations.rotate.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      rotateVal = Number(AnVal);
    }
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleVal scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
    // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "scale", "XML");
    if (
      pelInfo.animations.scale.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      scaleVal = Number(AnVal);
    }
    scaleAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXVal skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
    // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "skewX", "XML");
    if (
      pelInfo.animations.skewX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      skewXVal = Number(AnVal);
    }
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYVal skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
    // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "skewY", "XML");
    if (
      pelInfo.animations.skewY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      skewYVal = Number(AnVal);
    }
    skewYAnHtml = String(AnHtml);
  }
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
    // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
    // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 宽度_动画 widthVal;rectWidthAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rectWidth.enable) {
    // console.log("宽度_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rectWidth, "width", "XML");
    if (
      pelInfo.animations.left.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      widthVal = Number(AnVal);
    }
    rectWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 高度_动画 heightVal;rectHeightAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rectHeight.enable) {
    // console.log("高度_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rectHeight, "height", "XML");
    if (
      pelInfo.animations.left.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      heightVal = Number(AnVal);
    }
    rectHeightAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平移动_动画 leftVal;leftAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.left.enable) {
    // console.log("水平移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.left, "x", "XML");
    if (
      pelInfo.animations.left.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      leftVal = Number(AnVal);
    }
    leftAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 垂直移动_动画 topVal;topAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.top.enable) {
    // console.log("垂直移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.top, "y", "XML");
    if (
      pelInfo.animations.top.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      topVal = Number(AnVal);
    }
    topAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
    // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
    // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充颜色 fillVal;fillAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fill.enable) {
    // console.log("填充颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.fill, "fill", "CSS");
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillVal = String(AnVal);
    }
    fillAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
    // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
 /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
    // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
    // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓透明度 strokeOpacityVal;strokeOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeOpacity.enable) {
    // console.log("轮廓透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeOpacity,
      "stroke-opacity",
      "XML"
    );
    if (
      pelInfo.animations.strokeOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeOpacityVal = Number(AnVal);
    }
    strokeOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充透明度 fillOpacityVal;fillOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fillOpacity.enable) {
    // console.log("填充透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.fillOpacity,
      "fill-opacity",
      "XML"
    );
    if (
      pelInfo.animations.fillOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillOpacityVal = Number(AnVal);
    }
    fillOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    //-----------------------------------|公共动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动

    //------------------------------|属性-动画
    rectWidthAnHtml + //♈矩形宽度动画
    rectHeightAnHtml + //♈矩形高度动画
    leftAnHtml + //♈水平移动
    topAnHtml + //♈垂直移动
    strokeAnHtml + //♈轮廓颜色
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    fillAnHtml + //♈填充
    opacityAnHtml + //♈元素透明度
    strokeOpacityAnHtml + //♈轮廓透明度
    fillOpacityAnHtml; //♈填充透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // ——————————————————————————————————————————————————————————————| ★ 位置点
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: leftVal,
      y: topVal,
    },
    /** 左 */
    l: {
      x: leftVal,
      y: topVal + heightVal / 2,
    },
    /** 下左 */
    bl: {
      x: leftVal,
      y: topVal + heightVal,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: leftVal + widthVal / 2,
      y: topVal,
    },
    /** 中间 */
    m: {
      x: leftVal + widthVal / 2,
      y: topVal + heightVal / 2,
    },
    /** 下中 */
    bm: {
      x: leftVal + widthVal / 2,
      y: topVal + heightVal,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: leftVal + widthVal,
      y: topVal,
    },
    /** 右 */
    r: {
      x: leftVal + widthVal,
      y: topVal + heightVal / 2,
    },
    /** 下右 */
    br: {
      x: leftVal + widthVal,
      y: topVal + heightVal,
    },
  };

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  //填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;
  if (fillOptVal === 1/*颜色填充*/) {
    if (pidVal !== "none"/*父id不为空*/) {
      // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height=${heightVal} rx=${FXVal} ry=${FYVal} fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
      // console.log(pidVal)
      htmlLabel = `<g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height='${heightVal}' rx='${FXVal}' ry='${FYVal}' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g>`;
    }
  }
  if (fillOptVal === 2/*图案填充*/) {
    // 🐸 ★ 默认
    let defs = onPatternGenerator(fillPatternVal, fillVal, fillIdVal, fillSizeVal, fillRatioVal);
    // console.log(defs);
    if (pidVal !== "none"/*父id不为空*/) {
      // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height=${heightVal} rx=${FXVal} ry=${FYVal} fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
      // console.log(pidVal)
      htmlLabel = `<g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height='${heightVal}' rx='${FXVal}' ry='${FYVal}' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g>`;
    }
  }
  if (fillOptVal === 3/*线性渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><linearGradient id=${fillIdVal} x1=${fillX1Val}% y1=${fillY1Val}% x2=${fillX2Val}% y2=${fillY2Val}% >${offset}</linearGradient></defs>`

    if (pidVal !== "none"/*父id不为空*/) {
      // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height=${heightVal} rx=${FXVal} ry=${FYVal} fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
      // console.log(pidVal)
      htmlLabel = `<g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height='${heightVal}' rx='${FXVal}' ry='${FYVal}' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g>`;
    }
  }
  if (fillOptVal === 4/*放射渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><radialGradient id=${fillIdVal} cx=${fillCXVal}% cy=${fillCYVal}% r=${fillRVal}% >${offset}</radialGradient></defs>`

    if (pidVal !== "none"/*父id不为空*/) {
      // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height=${heightVal} rx=${FXVal} ry=${FYVal} fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
      // console.log(pidVal)
      htmlLabel = `<g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height='${heightVal}' rx='${FXVal}' ry='${FYVal}' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g>`;
    }
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，渲染-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(myStore.pelSet));
  copyPels.forEach((element: any) => {
    // console.log(element.key);
    if (element.key === pelInfo.key) {
      // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  myStore.pelSet = copyPels;

};

/** 渲染标签-多边形*/
const onRenderPolygon = (pelInfo: any): any => {
  // console.log("✍ 渲染标签-圆弧");

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);
  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  //------------------------------------------------
  /** 填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;*/
  let fillOptVal = Number(pelInfo.attrs.fill.fillOpt);
  /** 填充颜色*/
  let fillVal = String(pelInfo.attrs.fill.val);
  /** 填充图案*/
  let fillPatternVal = String(pelInfo.attrs.fill.fillPattern);
  /** 填充比例*/
  let fillRatioVal = Number(pelInfo.attrs.fill.fillRatio);
  /** 填充Id*/
  let fillIdVal = String(pelInfo.attrs.fill.fillId);
  /** 填充坐标x1*/
  let fillX1Val = Number(pelInfo.attrs.fill.fillX1);
  /** 填充坐标x2*/
  let fillX2Val = Number(pelInfo.attrs.fill.fillX2);
  /** 填充坐标y1*/
  let fillY1Val = Number(pelInfo.attrs.fill.fillY1);
  /** 填充坐标y2*/
  let fillY2Val = Number(pelInfo.attrs.fill.fillY2);
  /** 填充坐标cx*/
  let fillCXVal = Number(pelInfo.attrs.fill.fillCX);
  /** 填充坐标cy*/
  let fillCYVal = Number(pelInfo.attrs.fill.fillCY);
  /** 填充半径r*/
  let fillRVal = Number(pelInfo.attrs.fill.fillR);
  /** 填充偏移量*/
  let fillOffsetsVal = pelInfo.attrs.fill.offsets;

  /** 轮廓颜色*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 线链接样式 */
  let strokeLinejoinVal = String(pelInfo.attrs.strokeLinejoin.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);
  /** 轮廓透明度 */
  let strokeOpacityVal = Number(pelInfo.attrs.strokeOpacity.val);
  /** 填充透明度 */
  let fillOpacityVal = Number(pelInfo.attrs.fillOpacity.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画标签声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|变换-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平移动 */
  let translateXAnHtml = ``;
  /** 动画标签-垂直移动 */
  let translateYAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /** 动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-填充颜色*/
  let fillAnHtml = ``;
  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;
  /** 动画标签-轮廓透明度 */
  let strokeOpacityAnHtml = ``;
  /** 动画标签-填充透明度 */
  let fillOpacityAnHtml = ``;

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
    // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "roate", "XML");
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
    // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "scale", "XML");
    scaleAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平移动 translateXVal translateXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateX.enable) {
    // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateX, "", "XML");
    if (
      pelInfo.animations.translateX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateXVal = Number(AnVal);
    }
    translateXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直移动 translateYVal translateYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateY.enable) {
    // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateY, "", "XML");
    if (
      pelInfo.animations.translateY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateYVal = Number(AnVal);
    }
    translateYAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
    // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "skewX", "XML");
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
    // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "skewY", "XML");
    skewYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
    // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
    // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
    // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
    // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充颜色 fillVal;fillAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fill.enable) {
    // console.log("填充颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.fill, "fill", "CSS");
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillVal = String(AnVal);
    }
    fillAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
    // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
 /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
    // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
    // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓透明度 strokeOpacityVal;strokeOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeOpacity.enable) {
    // console.log("轮廓透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeOpacity,
      "stroke-opacity",
      "XML"
    );
    if (
      pelInfo.animations.strokeOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeOpacityVal = Number(AnVal);
    }
    strokeOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充透明度 fillOpacityVal;fillOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fillOpacity.enable) {
    // console.log("填充透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.fillOpacity,
      "fill-opacity",
      "XML"
    );
    if (
      pelInfo.animations.fillOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillOpacityVal = Number(AnVal);
    }
    fillOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    //-----------------------------------|公共动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    translateXAnHtml + //♈水平移动
    translateYAnHtml + //♈垂直移动
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动
    strokeAnHtml + //♈轮廓颜色
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    fillAnHtml + //♈填充
    opacityAnHtml + //♈元素透明度
    strokeOpacityAnHtml + //♈轮廓透明度
    fillOpacityAnHtml; //♈填充透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: 10,
      y: 10,
    },
    /** 左 */
    l: {
      x: 10,
      y: 10,
    },
    /** 下左 */
    bl: {
      x: 10,
      y: 10,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: 10,
      y: 10,
    },
    /** 中间 */
    m: {
      x: 10,
      y: 10,
    },
    /** 下中 */
    bm: {
      x: 10,
      y: 10,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: 10,
      y: 10,
    },
    /** 右 */
    r: {
      x: 10,
      y: 10,
    },
    /** 下右 */
    br: {
      x: 10,
      y: 10,
    },
  };

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 标签路径点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 路径点*/
  let pathPoints = pelInfo.attrs.pathPoints.val;
  // console.log(pathPoints)

  /** 路径追加点*/
  let PathAdd = "";
  for (let index = 1; index < pathPoints.length; index++) {
    let X = pathPoints[index].x;
    let Y = pathPoints[index].y;
    PathAdd = PathAdd + `L${X} ${Y} `;
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  //填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;
  if (fillOptVal === 1/*颜色填充*/) {
    if (pidVal !== "none"/*父id不为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='${fillVal}'>${anHtmlSet}</path></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='${fillVal}'>${anHtmlSet}</path></g>`;
    }
  }
  if (fillOptVal === 2/*图案填充*/) {
    if (pidVal !== "none"/*父id不为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='${fillVal}'>${anHtmlSet}</path></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='${fillVal}'>${anHtmlSet}</path></g>`;
    }
  }
  if (fillOptVal === 3/*线性渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><linearGradient id=${fillIdVal} x1=${fillX1Val}% y1=${fillY1Val}% x2=${fillX2Val}% y2=${fillY2Val}% >${offset}</linearGradient></defs>`

    if (pidVal !== "none"/*父id不为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='url(#${fillIdVal})' '>${anHtmlSet}</path></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='url(#${fillIdVal})' '>${anHtmlSet}</path></g>`;
    }
  }
  if (fillOptVal === 4/*放射渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><radialGradient id=${fillIdVal} cx=${fillCXVal}% cy=${fillCYVal}% r=${fillRVal}% >${offset}</radialGradient></defs>`

    if (pidVal !== "none"/*父id不为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='url(#${fillIdVal})' '>${anHtmlSet}</path></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
      // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='url(#${fillIdVal})' '>${anHtmlSet}</path></g>`;
    }
  }
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，渲染-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(myStore.pelSet));
  copyPels.forEach((element: any) => {
    // console.log(element.key);
    if (element.key === pelInfo.key) {
      // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  myStore.pelSet = copyPels;

};

/** 渲染标签-折线*/
const onRenderPolyline = (pelInfo: any): any => {
  // console.log("✍ 渲染标签-折线")

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);
  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 轮廓颜色*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 线链接样式 */
  let strokeLinejoinVal = String(pelInfo.attrs.strokeLinejoin.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画标签声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-开始点X */
  let startXAnHtml = ``;

  //------------------------------|变换-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平移动 */
  let translateXAnHtml = ``;
  /** 动画标签-垂直移动 */
  let translateYAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /** 动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-填充颜色*/
  let fillAnHtml = ``;
  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
    // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "roate", "XML");
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
    // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "scale", "XML");
    scaleAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平移动 translateXVal translateXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateX.enable) {
    // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateX, "", "XML");
    if (
      pelInfo.animations.translateX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateXVal = Number(AnVal);
    }
    translateXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直移动 translateYVal translateYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateY.enable) {
    // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateY, "", "XML");
    if (
      pelInfo.animations.translateY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateYVal = Number(AnVal);
    }
    translateYAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
    // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "skewX", "XML");
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
    // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "skewY", "XML");
    skewYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
    // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
    // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
    // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
    // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
    // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
 /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
    // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
    // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    /*开始点Y*/ startXAnHtml +
    //-----------------------------------|公共动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    translateXAnHtml + //♈水平移动
    translateYAnHtml + //♈垂直移动
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动
    strokeAnHtml + //♈轮廓颜色
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    fillAnHtml + //♈填充
    opacityAnHtml; //♈元素透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: 10,
      y: 10,
    },
    /** 左 */
    l: {
      x: 10,
      y: 10,
    },
    /** 下左 */
    bl: {
      x: 10,
      y: 10,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: 10,
      y: 10,
    },
    /** 中间 */
    m: {
      x: 10,
      y: 10,
    },
    /** 下中 */
    bm: {
      x: 10,
      y: 10,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: 10,
      y: 10,
    },
    /** 右 */
    r: {
      x: 10,
      y: 10,
    },
    /** 下右 */
    br: {
      x: 10,
      y: 10,
    },
  };

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 标签路径点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 路径点*/
  let pathPoints = pelInfo.attrs.pathPoints.val;
  /** 路径追加点*/
  let PathAdd = "";
  for (let index = 1; index < pathPoints.length; index++) {
    let X = pathPoints[index].x;
    let Y = pathPoints[index].y;
    PathAdd = PathAdd + `L${X},${Y} `;
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  if (pidVal !== "none") {
    // console.log(pidVal)
    htmlLabel =
      `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
      PathAdd +
      `' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' fill='rgba(0,0,0,0)'>${anHtmlSet}</path></g></svg></div>`;
  }
  if (pidVal === "none") {
    // console.log(pidVal)
    htmlLabel =
      `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
      PathAdd +
      `' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' fill='rgba(0,0,0,0)'>${anHtmlSet}</path></g>`;
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，渲染-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(myStore.pelSet));
  copyPels.forEach((element: any) => {
    // console.log(element.key);
    if (element.key === pelInfo.key) {
      // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  myStore.pelSet = copyPels;

};

/** 渲染标签-路径*/
const onRenderPath = (pelInfo: any): any => {
  // console.log("✍ 渲染标签-路径");

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 轮廓颜色*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画标签声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|变换-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平移动 */
  let translateXAnHtml = ``;
  /** 动画标签-垂直移动 */
  let translateYAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-开始点X */
  let startXAnHtml = ``;

  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /** 动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-填充颜色*/
  let fillAnHtml = ``;
  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;



  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
    // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "roate", "XML");
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
    // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "scale", "XML");
    scaleAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平移动 translateXVal translateXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateX.enable) {
    // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateX, "", "XML");
    if (
      pelInfo.animations.translateX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateXVal = Number(AnVal);
    }
    translateXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直移动 translateYVal translateYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateY.enable) {
    // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateY, "", "XML");
    if (
      pelInfo.animations.translateY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateYVal = Number(AnVal);
    }
    translateYAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
    // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "skewX", "XML");
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
    // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "skewY", "XML");
    skewYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
    // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
    // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
    // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
    // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
    // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
 /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
    // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
    // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    //-----------------------------------|公共动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    translateXAnHtml + //♈水平移动
    translateYAnHtml + //♈垂直移动
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动

    /*开始点Y*/ startXAnHtml +
    strokeAnHtml + //♈轮廓颜色
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    fillAnHtml + //♈填充
    opacityAnHtml; //♈元素透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: 10,
      y: 10,
    },
    /** 左 */
    l: {
      x: 10,
      y: 10,
    },
    /** 下左 */
    bl: {
      x: 10,
      y: 10,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: 10,
      y: 10,
    },
    /** 中间 */
    m: {
      x: 10,
      y: 10,
    },
    /** 下中 */
    bm: {
      x: 10,
      y: 10,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: 10,
      y: 10,
    },
    /** 右 */
    r: {
      x: 10,
      y: 10,
    },
    /** 下右 */
    br: {
      x: 10,
      y: 10,
    },
  };
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 深度拷贝-路径点*/
  let pathPoints = JSON.parse(JSON.stringify(pelInfo.attrs.pathPoints.val));
  /** 数包对象点 */
  let ListObjPoint = Object.values(pathPoints);
  /** 数包点 */
  let ListPoint: any[] = [];
  /** 遍历 数包对象点  生成 数包点*/
  ListObjPoint.forEach((Item: any) => {
    let tempList = Object.values(Item);
    ListPoint.push(tempList);
  });
  /** 线生成器 */
  let lineGenerator = d3.line().curve(d3.curveNatural);
  /** 路径字符串 */
  let PathString = lineGenerator(ListPoint);
  // console.log(PathString)

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  if (pidVal !== "none") {
    // console.log(pidVal)
    htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} id=${idVal} d='${PathString}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' fill='rgba(0,0,0,0)'>${anHtmlSet}</path></g></svg></div>`;
  }
  if (pidVal === "none") {
    // console.log(pidVal)
    htmlLabel = `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='${PathString}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' fill='rgba(0,0,0,0)'>${anHtmlSet}</path></g>`;
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，渲染-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(myStore.pelSet));
  copyPels.forEach((element: any) => {
    // console.log(element.key);
    if (element.key === pelInfo.key) {
      // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  myStore.pelSet = copyPels;

};

/** 渲染标签-Svg文本 */
const onRenderSvgText = (pelInfo: any): any => {
  // console.log("✍ 渲染标签-Svg文本")
  // console.log(pelInfo)
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 坐标 X*/
  let textLeftVal = Number(pelInfo.attrs.textLeft.val);
  /** 坐标 X*/
  let textTopVal = Number(pelInfo.attrs.textTop.val);

  //------------------------------------------------ 填充
  /** 填充颜色*/
  let fillVal = String(pelInfo.attrs.fill.val);
  /** 填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;*/
  let fillOptVal = (pelInfo.attrs.fill.fillOpt);
  /** 填充图案*/
  let fillPatternVal = Number(pelInfo.attrs.fill.fillPattern);
  /** 填充尺寸*/
  let fillSizeVal = Number(pelInfo.attrs.fill.fillSize);
  /** 填充比例*/
  let fillRatioVal = Number(pelInfo.attrs.fill.fillRatio);
  /** 填充Id*/
  let fillIdVal = String(pelInfo.attrs.fill.fillId);
  /** 填充坐标x1*/
  let fillX1Val = Number(pelInfo.attrs.fill.fillX1);
  /** 填充坐标x2*/
  let fillX2Val = Number(pelInfo.attrs.fill.fillX2);
  /** 填充坐标y1*/
  let fillY1Val = Number(pelInfo.attrs.fill.fillY1);
  /** 填充坐标y2*/
  let fillY2Val = Number(pelInfo.attrs.fill.fillY2);
  /** 填充坐标cx*/
  let fillCXVal = Number(pelInfo.attrs.fill.fillCX);
  /** 填充坐标cy*/
  let fillCYVal = Number(pelInfo.attrs.fill.fillCY);
  /** 填充半径r*/
  let fillRVal = Number(pelInfo.attrs.fill.fillR);
  /** 填充偏移量*/
  let fillOffsetsVal = pelInfo.attrs.fill.offsets;

  /** 轮廓颜色值*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 虚线值 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移值 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 文本高度 */
  let FontSizeVal = Number(pelInfo.attrs.fontSize.val);
  /** 文本字体 */
  let FontFamilyVal = String(pelInfo.attrs.fontFamily.val);
  /** 对齐方式*/
  let TextAnchorVal = String(pelInfo.attrs.textAnchor.val);
  /** 划线设置*/
  let TextDecorationVal = String(pelInfo.attrs.textDecoration.val);
  /** 文本样式*/
  let FontStyleVal = String(pelInfo.attrs.fontStyle.val);
  /** 文本样式*/
  let FontWeightVal = String(pelInfo.attrs.fontWeight.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);
  /** 轮廓透明度 */
  let strokeOpacityVal = Number(pelInfo.attrs.strokeOpacity.val);
  /** 填充透明度 */
  let fillOpacityVal = Number(pelInfo.attrs.fillOpacity.val);
  /** 文本内容 */
  let textContentVal = String(pelInfo.attrs.textContent.val);
  /** 使用路径文本 */
  let usePathVal = Boolean(pelInfo.attrs.pathText.usePath);
  /** 切线方向的偏移 */
  let dxVal = Number(pelInfo.attrs.pathText.dx);
  /** 法线方向的偏移 */
  let dyVal = Number(pelInfo.attrs.pathText.dy);
  /** 路径超文本标签 */
  let pathHtmlVal = String(pelInfo.attrs.pathText.pathHtml);
  /** 路径id */
  let pathIdVal = String(pelInfo.attrs.pathText.pathId);


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 声明动画标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|属性-动画标签

  //------------------------------|公共-动画标签 textContent
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;
  /** 动画标签-文本内容*/
  let textContentAnHtml = ``;
  /** 动画标签-填充颜色*/
  let fillAnHtml = ``;
  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /** 动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;
  /** 动画标签-轮廓透明度 */
  let strokeOpacityAnHtml = ``;
  /** 动画标签-填充透明度 */
  let fillOpacityAnHtml = ``;

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
    // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
    // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 文本内容 textContentVal;textContentAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.textContent.enable) {
    // console.log("文本内容 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.textContent, "", "XML");
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      textContentVal = String(AnVal);
    }
    textContentAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充颜色 fillVal;fillAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fill.enable) {
    // console.log("填充颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.fill, "fill", "CSS");
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillVal = String(AnVal);
    }
    fillAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
    // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
 /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
    // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
    // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
    // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
    // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓透明度 strokeOpacityVal;strokeOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeOpacity.enable) {
    // console.log("轮廓透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeOpacity,
      "stroke-opacity",
      "XML"
    );
    if (
      pelInfo.animations.strokeOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeOpacityVal = Number(AnVal);
    }
    strokeOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充透明度 fillOpacityVal;fillOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fillOpacity.enable) {
    // console.log("填充透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.fillOpacity,
      "fill-opacity",
      "XML"
    );
    if (
      pelInfo.animations.fillOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillOpacityVal = Number(AnVal);
    }
    fillOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    //-----------------------------------|公共动画
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动
    textContentAnHtml + //♈文本内容
    strokeAnHtml + //♈轮廓颜色
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    fillAnHtml + //♈填充
    opacityAnHtml + //♈元素透明度
    strokeOpacityAnHtml + //♈轮廓透明度
    fillOpacityAnHtml; //♈填充透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: textLeftVal - 5,
      y: textTopVal - 5,
    },
    /** 左 */
    l: {
      x: textLeftVal - 5,
      y: textTopVal,
    },
    /** 下左 */
    bl: {
      x: textLeftVal - 5,
      y: textTopVal + 5,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: textLeftVal,
      y: textTopVal - 5,
    },
    /** 中间 */
    m: {
      x: textLeftVal,
      y: textTopVal,
    },
    /** 下中 */
    bm: {
      x: textLeftVal,
      y: textTopVal + 5,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: textLeftVal + 5,
      y: textTopVal - 5,
    },
    /** 右 */
    r: {
      x: textLeftVal + 5,
      y: textTopVal,
    },
    /** 下右 */
    br: {
      x: textLeftVal + 5,
      y: textTopVal + 5,
    },
  };
  // console.log(PlacePoint)

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  // 🐸 路径定义
  let pathDefs = `<defs><path id=${pathIdVal} d=${pathHtmlVal} stroke="rgba(0,0,0,0)" fill="none"/></defs>`
  // 🐸 文本路径定义
  let textPathDefs = `<textPath xlink:href="#${pathIdVal}">${textContentVal}</textPath></text>`;
  if (fillOptVal === 1/*颜色填充*/) {
    if (pidVal !== "none") {
      // 不使用路径文本
      if (!usePathVal) {
        htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><text id=${idVal} x='${textLeftVal}' y='${textTopVal}' style="stroke:${strokeVal}; stroke-width:${strokeWidthVal}; stroke-dasharray:${strokeDasharrayVal}; stroke-dashoffset:${strokeDashoffsetVal}; stroke:${strokeVal};fill:${fillVal};font-size:${FontSizeVal}px; font-family:${FontFamilyVal}; text-anchor:${TextAnchorVal}; text-decoration:${TextDecorationVal};font-style:${FontStyleVal};font-weight:${FontWeightVal};opacity:${opacityVal};stroke-opacity:${strokeOpacityVal};fill-opacity:${fillOpacityVal};">${textContentVal}${anHtmlSet}</text></svg></div>`;
      }
      // 使用路径文本
      if (usePathVal) {
        htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g>${pathDefs}<text id=${idVal} dx='${dxVal}' dy='${dyVal}' style="stroke:${strokeVal}; stroke-width:${strokeWidthVal}; stroke-dasharray:${strokeDasharrayVal}; stroke-dashoffset:${strokeDashoffsetVal}; stroke:${strokeVal};fill:${fillVal};font-size:${FontSizeVal}px; font-family:${FontFamilyVal}; text-anchor:${TextAnchorVal}; text-decoration:${TextDecorationVal};font-style:${FontStyleVal};font-weight:${FontWeightVal};opacity:${opacityVal};stroke-opacity:${strokeOpacityVal};fill-opacity:${fillOpacityVal};">${textPathDefs}${anHtmlSet}</text></g></svg></div>`;
      }
    }
    if (pidVal === "none") {
      // 不使用路径文本
      if (!usePathVal) {
        htmlLabel = `<text id=${idVal} x='${textLeftVal}' y='${textTopVal}' style="stroke:${strokeVal}; stroke-width:${strokeWidthVal}; stroke-dasharray:${strokeDasharrayVal}; stroke-dashoffset:${strokeDashoffsetVal}; stroke:${strokeVal};fill:${fillVal};font-size:${FontSizeVal}px; font-family:${FontFamilyVal}; text-anchor:${TextAnchorVal}; text-decoration:${TextDecorationVal};font-style:${FontStyleVal};font-weight:${FontWeightVal};opacity:${opacityVal};stroke-opacity:${strokeOpacityVal};fill-opacity:${fillOpacityVal};">${textContentVal}${anHtmlSet}</text>`;
      }
      // 使用路径文本
      if (usePathVal) {
        htmlLabel = `<g>${pathDefs}<text id=${idVal} dx='${dxVal}' dy='${dyVal}' style="stroke:${strokeVal}; stroke-width:${strokeWidthVal}; stroke-dasharray:${strokeDasharrayVal}; stroke-dashoffset:${strokeDashoffsetVal}; stroke:${strokeVal};fill:${fillVal};font-size:${FontSizeVal}px; font-family:${FontFamilyVal}; text-anchor:${TextAnchorVal}; text-decoration:${TextDecorationVal};font-style:${FontStyleVal};font-weight:${FontWeightVal};opacity:${opacityVal};stroke-opacity:${strokeOpacityVal};fill-opacity:${fillOpacityVal};">${textPathDefs}${anHtmlSet}</text></g>`;
      }
    }
  }
  if (fillOptVal === 2/*图案填充*/) {
    // 🐸 ★ 默认
    let defs = onPatternGenerator(fillPatternVal, fillVal, fillIdVal, fillSizeVal, fillRatioVal);
    // console.log(defs);
    if (pidVal !== "none") {
      // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g>${defs}<text id=${idVal} x='${textLeftVal}' y='${textTopVal}' stroke=${strokeVal} stroke-width=${strokeWidthVal} stroke-dasharray=${strokeDasharrayVal} stroke-dashoffset=${strokeDashoffsetVal} stroke=${strokeVal} fill=url(#${fillIdVal}) font-size=${FontSizeVal}px font-family=${FontFamilyVal} text-anchor=${TextAnchorVal} text-decoration=${TextDecorationVal} font-style=${FontStyleVal} font-weight=${FontWeightVal} opacity:${opacityVal} stroke-opacity=${strokeOpacityVal} fill-opacity=${fillOpacityVal}>${textContentVal}${anHtmlSet}</text></g></svg></div>`;
    }
    if (pidVal === "none") {
      // console.log(pidVal)
      htmlLabel = `<g>${defs}<text id=${idVal} x='${textLeftVal}' y='${textTopVal}' stroke=${strokeVal} stroke-width=${strokeWidthVal} stroke-dasharray=${strokeDasharrayVal} stroke-dashoffset=${strokeDashoffsetVal} stroke=${strokeVal} fill=url(#${fillIdVal}) font-size=${FontSizeVal}px font-family=${FontFamilyVal} text-anchor=${TextAnchorVal} text-decoration=${TextDecorationVal} font-style=${FontStyleVal} font-weight=${FontWeightVal} opacity:${opacityVal} stroke-opacity=${strokeOpacityVal} fill-opacity=${fillOpacityVal}>${textContentVal}${anHtmlSet}</text></g>`;
    }
  }
  if (fillOptVal === 3/*线性渐变填充*/) {

    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }

    // 🐸 ★ 默认
    let defs = `<defs><linearGradient id=${fillIdVal} x1=${fillX1Val}% y1=${fillY1Val}% x2=${fillX2Val}% y2=${fillY2Val}% >${offset}</linearGradient></defs>`

    if (pidVal !== "none") {
      // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g>${defs}<text id=${idVal} x='${textLeftVal}' y='${textTopVal}' stroke=${strokeVal} stroke-width=${strokeWidthVal} stroke-dasharray=${strokeDasharrayVal} stroke-dashoffset=${strokeDashoffsetVal} stroke=${strokeVal} fill=url(#${fillIdVal}) font-size=${FontSizeVal}px font-family=${FontFamilyVal} text-anchor=${TextAnchorVal} text-decoration=${TextDecorationVal} font-style=${FontStyleVal} font-weight=${FontWeightVal} opacity:${opacityVal} stroke-opacity=${strokeOpacityVal} fill-opacity=${fillOpacityVal}>${textContentVal}${anHtmlSet}</text></g></svg></div>`;
    }
    if (pidVal === "none") {

      // console.log(pidVal)
      htmlLabel = `<g>${defs}<text id=${idVal} x='${textLeftVal}' y='${textTopVal}' stroke=${strokeVal} stroke-width=${strokeWidthVal} stroke-dasharray=${strokeDasharrayVal} stroke-dashoffset=${strokeDashoffsetVal} stroke=${strokeVal} fill=url(#${fillIdVal}) font-size=${FontSizeVal}px font-family=${FontFamilyVal} text-anchor=${TextAnchorVal} text-decoration=${TextDecorationVal} font-style=${FontStyleVal} font-weight=${FontWeightVal} opacity:${opacityVal} stroke-opacity=${strokeOpacityVal} fill-opacity=${fillOpacityVal}>${textContentVal}${anHtmlSet}</text></g>`;
    }
  }
  if (fillOptVal === 4/*放射渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><radialGradient id=${fillIdVal} cx=${fillCXVal}% cy=${fillCYVal}% r=${fillRVal}% >${offset}</radialGradient></defs>`
    if (pidVal !== "none") {
      // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g>${defs}<text id=${idVal} x='${textLeftVal}' y='${textTopVal}' stroke=${strokeVal} stroke-width=${strokeWidthVal} stroke-dasharray=${strokeDasharrayVal} stroke-dashoffset=${strokeDashoffsetVal} stroke=${strokeVal} fill=url(#${fillIdVal}) font-size=${FontSizeVal}px font-family=${FontFamilyVal} text-anchor=${TextAnchorVal} text-decoration=${TextDecorationVal} font-style=${FontStyleVal} font-weight=${FontWeightVal} opacity:${opacityVal} stroke-opacity=${strokeOpacityVal} fill-opacity=${fillOpacityVal}>${textContentVal}${anHtmlSet}</text></g></svg></div>`;
    }
    if (pidVal === "none") {
      // console.log(pidVal)
      htmlLabel = `<g>${defs}<text id=${idVal} x='${textLeftVal}' y='${textTopVal}' stroke=${strokeVal} stroke-width=${strokeWidthVal} stroke-dasharray=${strokeDasharrayVal} stroke-dashoffset=${strokeDashoffsetVal} stroke=${strokeVal} fill=url(#${fillIdVal}) font-size=${FontSizeVal}px font-family=${FontFamilyVal} text-anchor=${TextAnchorVal} text-decoration=${TextDecorationVal} font-style=${FontStyleVal} font-weight=${FontWeightVal} opacity:${opacityVal} stroke-opacity=${strokeOpacityVal} fill-opacity=${fillOpacityVal}>${textContentVal}${anHtmlSet}</text></g>`;
    }
  }
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，渲染-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(myStore.pelSet));
  copyPels.forEach((element: any) => {
    // console.log(element.key);
    if (element.key === pelInfo.key) {
      // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  myStore.pelSet = copyPels;

};

/** 渲染标签-svg图片*/
const onRenderDIVImage = (pelInfo: any): any => {
  // console.log("✍ 渲染标签-svg图片")
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  /** 坐标 X */
  let left = Number(pelInfo.attrs.left.val);
  /** 坐标 X */
  let top = Number(pelInfo.attrs.top.val);
  /** 宽度值 */
  let width = Number(pelInfo.attrs.width.val);
  /** 高度值 */
  let height = Number(pelInfo.attrs.height.val);
  /** 图片数据  */
  let imageData = String(pelInfo.attrs.imageData.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 建立 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: left,
      y: top,
    },
    /** 左 */
    l: {
      x: left,
      y: top + height / 2,
    },
    /** 下左 */
    bl: {
      x: left,
      y: top + height,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: left + width / 2,
      y: top,
    },
    /** 中间 */
    m: {
      x: left + width / 2,
      y: top + height / 2,
    },
    /** 下中 */
    bm: {
      x: left + width / 2,
      y: top + height,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: left + width,
      y: top,
    },
    /** 右 */
    r: {
      x: left + width,
      y: top + height / 2,
    },
    /** 下右 */
    br: {
      x: left + width,
      y: top + height,
    },
  };

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  if (pidVal !== "none") {
    htmlLabel = `<g vector-effect="non-scaling-stroke"><image preserveAspectRatio="none" vector-effect="non-scaling-stroke"  xlink:href='${imageData}' x='${left}px' y='${top}px' width='${width}px' height='${height}px'></image></g>`;
  }
  if (pidVal === "none") {
    htmlLabel = `<g vector-effect="non-scaling-stroke"><image preserveAspectRatio="none" vector-effect="non-scaling-stroke" xlink:href=${imageData} x='${left}px' y='${top}px' width='${width}px' height='${height}px'></image></g>`;
  }
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，渲染-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(myStore.pelSet));
  copyPels.forEach((element: any) => {
    // console.log(element.key);
    if (element.key === pelInfo.key) {
      // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  myStore.pelSet = copyPels;

};


/**————————————————————————————————————————————————————————————————————————————————————————————————*/
//                                ★ DIV图元
/**————————————————————————————————————————————————————————————————————————————————————————————————*/
/** 渲染标签-DIV文本 */
const onRenderDIVText = (pelInfo: any): any => {
  // console.log("✍ 渲染标签-DIV文本")
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);
  /** 坐标x */
  let leftVal = Number(pelInfo.attrs.left.val);
  /** 坐标y */
  let topVal = Number(pelInfo.attrs.top.val);
  /** 宽 */
  let widthVal = Number(pelInfo.attrs.width.val);
  /** 高  */
  let heightVal = Number(pelInfo.attrs.height.val);
  /** 旋转角度 */
  let rotateVal = Number(pelInfo.attrs.rotate.val);
  /** 边框宽度 */
  let borderWidthVal = Number(pelInfo.attrs.borderWidth.val);
  /** 边框样式 */
  let borderStyleVal = String(pelInfo.attrs.borderStyle.val);
  /** 边框颜色 */
  let borderColorVal = String(pelInfo.attrs.borderColor.val);
  /** 边框圆角 */
  let borderRadiusVal = String(pelInfo.attrs.borderRadius.val);
  /** 文本高度 */
  let fontSizeVal = String(pelInfo.attrs.fontSize.val);
  /** 字符之间的间距 */
  let letterSpacVal = String(pelInfo.attrs.letterSpac.val);
  /** 字间距*/
  let wordSpacVal = String(pelInfo.attrs.wordSpac.val);
  /** 文本样式 */
  let fontStyleVal = String(pelInfo.attrs.fontStyle.val);
  /** 文本字体 */
  let fontFamilyVal = String(pelInfo.attrs.fontFamily.val);
  /** 粗细 */
  let fontWeightVal = String(pelInfo.attrs.fontWeight.val);
  /** 文本水平对齐方式 */
  let textAlignVal = String(pelInfo.attrs.textAlign.val);
  /** 第一行的缩进 */
  let textIndentVal = Number(pelInfo.attrs.textIndent.val);
  /** 行高 */
  let rowHeightVal = Number(pelInfo.attrs.rowHeight.val);
  /** 字体内容 */
  let fontContentVal = String(pelInfo.attrs.fontContent.val);
  /** 字体颜色 */
  let fontColorVal = String(pelInfo.attrs.fontColor.val);
  /** 背景颜色 */
  let backgroundColorVal = String(pelInfo.attrs.backgroundColor.val);
  /** 水平阴影 */
  let shadowHorizontalVal = String(pelInfo.attrs.shadowHorizontal.val);
  /** 垂直阴影 */
  let shadowVerticalVal = String(pelInfo.attrs.shadowVertical.val);
  /** 模糊阴影 */
  let shadowvagueVal = String(pelInfo.attrs.shadowvague.val);
  /** 阴影颜色 */
  let shadowColorVal = String(pelInfo.attrs.shadowColor.val);
  /** 叠放层级  */
  let zIndex = Number(pelInfo.attrs.zIndex.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: leftVal,
      y: topVal,
    },
    /** 左 */
    l: {
      x: leftVal,
      y: topVal + heightVal / 2,
    },
    /** 下左 */
    bl: {
      x: leftVal,
      y: topVal + heightVal,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: leftVal + widthVal / 2,
      y: topVal,
    },
    /** 中间 */
    m: {
      x: leftVal + widthVal / 2,
      y: topVal + heightVal / 2,
    },
    /** 下中 */
    bm: {
      x: leftVal + widthVal / 2,
      y: topVal + heightVal,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: leftVal + widthVal,
      y: topVal,
    },
    /** 右 */
    r: {
      x: leftVal + widthVal,
      y: topVal + heightVal / 2,
    },
    /** 下右 */
    br: {
      x: leftVal + widthVal,
      y: topVal + heightVal,
    },
  };
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = `<div style='position: absolute;width: ${widthVal}px; height: ${heightVal}px;top: ${topVal}px; left: ${leftVal}px; border: ${borderWidthVal}px ${borderStyleVal} ${borderColorVal};border-radius: ${borderRadiusVal}px; transform: rotate(${rotateVal}deg);font-size: ${fontSizeVal}px;text-indent: ${textIndentVal}px;line-height: ${rowHeightVal};letter-spacing: ${letterSpacVal}px;word-spacing: ${wordSpacVal}px; font-style: ${fontStyleVal};font-weight: ${fontWeightVal};font-family: ${fontFamilyVal};text-align: ${textAlignVal};text-shadow: ${shadowHorizontalVal}px ${shadowVerticalVal}px ${shadowvagueVal}px ${shadowColorVal};background-color: ${backgroundColorVal};color: ${fontColorVal};z-index:${zIndex};'>${fontContentVal}</div>`;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，渲染-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(myStore.pelSet));
  copyPels.forEach((element: any) => {
    // console.log(element.key);
    if (element.key === pelInfo.key) {
      // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  myStore.pelSet = copyPels;

};


/** 渲染标签-DIV块 */
const onRenderDIVBlock = (pelInfo: any): any => {
  // console.log("✍ 渲染标签-DIV块")
  // console.log(pelInfo)
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 视图盒子x坐标 */
  let boxLeftVal = Number(pelInfo.attrs.boxLeft.val);
  /** 视图盒子y坐标 */
  let boxTopVal = Number(pelInfo.attrs.boxTop.val);
  /** 视图盒子宽 */
  let boxWidthVal = Number(pelInfo.attrs.boxWidth.val);
  /** 视图盒子高 */
  let boxHeightVal = Number(pelInfo.attrs.boxHeight.val);


  let left = Number(pelInfo.attrs.left.val);
  let top = Number(pelInfo.attrs.top.val);
  let width = Number(pelInfo.attrs.width.val);
  let height = Number(pelInfo.attrs.height.val);

  /** 叠放层级  */
  let zIndex = Number(pelInfo.attrs.zIndex.val);
  /** 旋转  */
  let rotate = Number(pelInfo.attrs.rotate.val);
  /** 块标签  */
  let blockHtml = pelInfo.attrs.blockHtml.val;

  //-----------------------------------|公共动画
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画标签声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|公共-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平移动 */
  let translateXAnHtml = ``;
  /** 动画标签-垂直移动 */
  let translateYAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-水平动画 */
  let leftAnHtml = ``;
  /** 动画标签-垂直动画 */
  let topAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateVal rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
    // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "roate", "XML");
    if (
      pelInfo.animations.rotate.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      rotateVal = Number(AnVal);
    }
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleVal scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
    // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "", "XML");
    if (
      pelInfo.animations.scale.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      scaleVal = Number(AnVal);
    }
    scaleAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平移动 translateXVal translateXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateX.enable) {
    // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateX, "", "XML");
    if (
      pelInfo.animations.translateX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateXVal = Number(AnVal);
    }
    translateXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直移动 translateYVal translateYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateY.enable) {
    // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateY, "", "XML");
    if (
      pelInfo.animations.translateY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateYVal = Number(AnVal);
    }
    translateYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXVal skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
    // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "", "XML");
    if (
      pelInfo.animations.skewX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      skewXVal = Number(AnVal);
    }
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYVal skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
    // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "", "XML");
    if (
      pelInfo.animations.skewY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      skewYVal = Number(AnVal);
    }
    skewYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
    // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
    // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    //-----------------------------------|公共动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    translateXAnHtml + //♈水平移动
    translateYAnHtml + //♈垂直移动
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml //♈路径移动
    ;

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: left,
      y: top,
    },
    /** 左 */
    l: {
      x: left,
      y: top + height / 2,
    },
    /** 下左 */
    bl: {
      x: left,
      y: top + height,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: left + width / 2,
      y: top,
    },
    /** 中间 */
    m: {
      x: left + width / 2,
      y: top + height / 2,
    },
    /** 下中 */
    bm: {
      x: left + width / 2,
      y: top + height,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: left + width,
      y: top,
    },
    /** 右 */
    r: {
      x: left + width,
      y: top + height / 2,
    },
    /** 下右 */
    br: {
      x: left + width,
      y: top + height,
    },
  };

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``
  if (pidVal !== "none") {
    htmlLabel = `<div style='position: absolute;width:${width}px; height:${height}px;top: ${top}px; left: ${left}px;transform: rotate(${rotate}deg); z-index:${zIndex};'><svg width=${width} height=${height} version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='${boxLeftVal} ${boxTopVal} ${boxWidthVal} ${boxHeightVal}'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${blockHtml} ${anHtmlSet}</g></svg></div>`;
  }
  if (pidVal === "none") {
    htmlLabel = `<div style='position: absolute;width:${width}px; height:${height}px;top: ${top}px; left: ${left}px;transform: rotate(${rotate}deg); z-index:${zIndex};'><svg width=${width} height=${height} version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  viewBox='${boxLeftVal} ${boxTopVal} ${boxWidthVal} ${boxHeightVal}'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${blockHtml} ${anHtmlSet}</g></svg></div>`;
  }
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，渲染-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(myStore.pelSet));
  copyPels.forEach((element: any) => {
    // console.log(element.key);
    if (element.key === pelInfo.key) {
      // console.log(element);
      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  myStore.pelSet = copyPels;

};

/** 渲染标签-包*/
const onUpdataHtmWrap = (pelInfo: any) => {
  // console.log("✍ 渲染标签-包")
  // console.log(pelInfo)
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  /** 旋转值*/
  let rotateVal = Number(pelInfo.attrs.rotate.val);
  /** 缩放值*/
  let scaleVal = Number(pelInfo.attrs.scale.val);
  /** 水平拉伸*/
  let skewXVal = Number(pelInfo.attrs.skewX.val);
  /** 垂直拉伸*/
  let skewYVal = Number(pelInfo.attrs.skewY.val);
  /** 坐标X值*/
  let leftVal = Number(pelInfo.attrs.left.val);
  /** 坐标Y值*/
  let topVal = Number(pelInfo.attrs.top.val);
  /** 叠放层级  */
  let zIndexVal = Number(pelInfo.attrs.zIndex.val);
  /** 画布宽度 */
  let canvasWidth = Number(myStore.canvasAttr.canvasWidth);
  /** 画布高度 */
  let canvasHeight = Number(myStore.canvasAttr.canvasHeight);
  /** 宽度值 */
  let widthVal = canvasWidth / scaleVal;
  /** 高度值 */
  let heightVal = canvasHeight / scaleVal;

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 声明动画标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-水平动画 */
  let leftAnHtml = ``;
  /** 动画标签-垂直动画 */
  let topAnHtml = ``;
  /** 动画标签-圆半径 */
  let radiusAnHtml = ``;

  //------------------------------|公共-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml; //♈路径移动

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历子数据
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  try {
    if (pelInfo.children.length > 0) {
      // console.log("★ pelInfo.children.length > 0 遍历")
      let ErgodicData = pelInfo.children;
      // 🐸  ★ 迭代-遍历子数据
      function wrapUpdata(ErgodicData: any) {
        // console.log("包裹迭代-遍历子数据")
        ErgodicData.forEach((pelDate: any) => {
          let PelType = pelDate.type;
          // console.log(SvgDate)
          if (
            PelType === "horizontaLine" /*水平线*/ ||
            PelType === "verticalLine" /*垂直线*/ ||
            PelType === "slantLine" /*斜线*/
          ) {
            htmlLabel = htmlLabel + onRenderLine(pelDate);
          }
          if (PelType === "circle" /*圆*/) {
            htmlLabel = htmlLabel + onRenderCircle(pelDate);
          }
          if (PelType === "ellipse" /*椭圆*/) {
            htmlLabel = htmlLabel + onRenderEllipse(pelDate);
          }
          if (PelType === "arc" /*三点弧线*/) {
            htmlLabel = htmlLabel + onRenderArc(pelDate);
          }
          if (PelType === "circlePolygon" /*圆分多边形*/) {
            htmlLabel = htmlLabel + onRenderCirclePolygon(pelDate);
          }
          if (PelType === "rectangle" /*矩形*/) {
            htmlLabel = htmlLabel + onRenderRectangle(pelDate);
          }
          if (PelType === "sector" /*扇形*/) {
          }
          if (PelType === "polygon" /*多边形*/) {
            htmlLabel = htmlLabel + onRenderPolygon(pelDate);
          }
          if (PelType === "polyline" /*折线*/) {
            htmlLabel = htmlLabel + onRenderPolyline(pelDate);
          }
          if (PelType === "path" /*路径*/) {
            htmlLabel = htmlLabel + onRenderPath(pelDate);
          }
          if (PelType === "svgText" /*Svg文本*/) {
            htmlLabel = htmlLabel + onRenderSvgText(pelDate);
          }
          // ————————————————————————————————————————————————————————————————————————————————| DIV图元
          if (PelType === "divText" /*DIV文本*/) {
            htmlLabel = htmlLabel + onRenderDIVText(pelDate);
          }
          if (PelType === "svgImage" /*图片*/) {
            htmlLabel = htmlLabel + onRenderDIVImage(pelDate);
          }
          if (PelType === "divBlock" /*DIV块*/) {
            htmlLabel = htmlLabel + onRenderDIVBlock(pelDate);
          }

          /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
          // 🐸 迭代
          /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
          try {
            if (pelDate.children.length > 0) {
              // console.log("有子数据-分边遍历")
              let childrenData = pelDate.children;
              childrenData.forEach((element: any) => {
                wrapUpdata(element);
              });
            }
          } catch (error) { }
        });
      }
      wrapUpdata(ErgodicData);
      // console.log(htmlLabel)
    }
  } catch (error) { }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 合并标签及动画
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let mergeHtml = `<div id=${idVal} style='position:absolute;width:1024px; height:1024px;top:${topVal}px; left:${leftVal}px;transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg); z-index:${zIndexVal};'>${htmlLabel} ${anHtmlSet}</div>`;

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // ——————————————————————————————————————————————————————————————| ★ 位置点
  /** 位置点 */
  let PlacePoint: PlaceType = {
    /** 上左 */
    tl: {
      x: leftVal,
      y: topVal,
    },
    /** 上中 */
    tm: {
      x: leftVal + widthVal / 2,
      y: topVal,
    },
    /** 上右 */
    tr: {
      x: leftVal + widthVal,
      y: topVal,
    },
    /** 左 */
    l: {
      x: leftVal,
      y: topVal + heightVal / 2,
    },
    /** 中间 */
    m: {
      x: leftVal + widthVal / 2,
      y: topVal + heightVal / 2,
    },
    /** 右 */
    r: {
      x: leftVal + widthVal,
      y: topVal + heightVal / 2,
    },
    /** 下左 */
    bl: {
      x: leftVal,
      y: topVal + heightVal,
    },
    /** 下中 */
    bm: {
      x: leftVal + widthVal / 2,
      y: topVal + heightVal,
    },
    /** 下右 */
    br: {
      x: leftVal + widthVal,
      y: topVal + heightVal,
    },
  };


  /** 深度拷贝-图元数据 */
  let copyPels = JSON.parse(JSON.stringify(myStore.pelSet));

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，渲染-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  for (let indexA = 0; indexA < copyPels.length; indexA++) {
    let pelItem = copyPels[indexA];
    // console.log(element.key);
    if (pelItem.key === pelInfo.key) {
      // console.log(element);
      pelItem.attrs.wrapHtml.val = mergeHtml; // 文本标记标签
      pelItem.htmls = mergeHtml; // 文本标记标签
      pelItem.place = PlacePoint; // 位置点
    }
  };
  myStore.pelSet = copyPels;

};

/**————————————————————————————————————————————————————————————————————————————————————————————————*/
//                                ★ 渲染-标签
/**————————————————————————————————————————————————————————————————————————————————————————————————*/

/** 渲染画布*/
export const onRenderCanvas = () => {
  console.log("渲染画布")
  // let Canvas = document.querySelector("#h_canvas") as HTMLCanvasElement
  // let ctx = Canvas.getContext('2d');
  // ctx?.clearRect(0, 0, 0, 0)

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历 图元数据
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let pelSet = JSON.parse(JSON.stringify(myStore.pelSet))
  pelSet.forEach((pelInfo: any /*图元参数*/) => {
    /** 图元类 */
    let PelType = pelInfo.type;
    // console.log(PelType)
    if (PelType === "wrap" /*包*/) {
      onUpdataHtmWrap(pelInfo);
    }
    if (
      PelType === "horizontaLine" /*水平线*/ ||
      PelType === "verticalLine" /*垂直线*/ ||
      PelType === "slantLine" /*斜线*/
    ) {
      onRenderLine(pelInfo);
    }
    if (PelType === "circle" /*圆*/) {
      onRenderCircle(pelInfo);
    }
    if (PelType === "ellipse" /*椭圆*/) {
      onRenderEllipse(pelInfo);
    }
    if (PelType === "arc" /*三点弧线*/) {
      onRenderArc(pelInfo);
    }
    if (PelType === "circlePolygon" /*圆分多边形*/) {
      onRenderCirclePolygon(pelInfo);
    }
    if (PelType === "rectangle" /*矩形*/) {
      onRenderRectangle(pelInfo);
    }
    if (PelType === "sector" /*扇形*/) {
    }
    if (PelType === "polygon" /*多边形*/) {
      onRenderPolygon(pelInfo);
    }
    if (PelType === "polyline" /*折线*/) {
      onRenderPolyline(pelInfo);
    }
    if (PelType === "path" /*路径*/) {
      onRenderPath(pelInfo);
    }
    if (PelType === "svgText" /*Svg文本*/) {
      onRenderSvgText(pelInfo);
    }
    if (PelType === "svgImage" /*图片*/) {
      onRenderDIVImage(pelInfo);
    }
    // ————————————————————————————————————————————————————————————————————————————————| DIV图元
    if (PelType === "divText" /*DIV文本*/) {
      onRenderDIVText(pelInfo);
    }
    if (PelType === "divBlock" /*DIV块*/) {
      onRenderDIVBlock(pelInfo);
    }
  });
};



